package com.miuugo.common.tools;

import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.util.Random;

/**
 * AES Utils 加密工具类
 * @author qiyunhao
 */
@SuppressWarnings("all")
public class AESUtil {

    /**
     * byte数组转字符串
     * @param byte1
     * @return
     * @throws UnsupportedEncodingException
     */
    public static String byteToString(byte[] byte1) throws UnsupportedEncodingException {
        return new String(byte1);
    }

    /**
     * 加密时调用方法，三个参数分别是：明文，密钥，向量，注意向量的长度只能是16byte，而且加密解密时必须使用一致的向量。
     * @param content
     * @param keyBytes
     * @param iv
     * @return
     */
    public static byte[] AES_CBC_Encrypt(byte[] content, byte[] keyBytes,
                                         byte[] iv) {

        try {
            SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
            byte[] result = cipher.doFinal(content);
            return result;
        } catch (Exception e) {
            System.out.println("exception:" + e.toString());
        }
        return null;
    }

    /**
     * 解密方法，三个参数：密文，密钥，向量
     * @param content
     * @param keyBytes
     * @param iv
     * @return
     */
    public static byte[] AES_CBC_Decrypt(byte[] content, byte[] keyBytes,
                                         byte[] iv) {

        try {
            SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
            byte[] result = cipher.doFinal(content);
            return result;
        } catch (Exception e) {
            // TODO Auto-generated catchblock
            System.out.println("exception:" + e.toString());
        }
        return null;
    }

    /**
     *将base64类型的字符串转成byte类型
     * @param key
     * @return
     * @throws Exception
     */
    public static byte[] decryptBASE64(String key) throws Exception {
        return Base64.decodeBase64(key.getBytes());
    }

    /**
     * 将byte类型转变为base64类型的字符串
     * @param key
     * @return
     * @throws Exception
     */
    public static String encryptBASE64(byte[] key) throws Exception {
        return new String(Base64.encodeBase64(key));
    }
    /**
     * 这个方法在大多数时候是用不到的，可以选择无视。
     * @param src byte数组
     * @return 十六进制的字符串
     */
    public static String bytesToHexString(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder();
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }

    /**
     * 字符串转二进制字符串
     *
     * @param str
     */

    public String toBinary(String str) {

        char[] strChar = str.toCharArray();
        String result = "";
        for (int i = 0; i < strChar.length; i++) {
            result += Integer.toBinaryString(strChar[i]) + "";
        }

        return result;
    }

    /**
     * 字符串转16进制字符串
     * @param s
     * @return
     */
    public static String strTo16(String s) {
        String str = "";
        for (int i = 0; i < s.length(); i++) {
            int ch = (int) s.charAt(i);
            String s4 = Integer.toHexString(ch);
            str = str + s4;
        }
        return str;
    }


    /**
     * 得到一个任意长度随即密钥
     * @param KeyLength
     * @return
     */
    public static String KeyCreate(int KeyLength) {

        String base = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678";
        Random random = new Random();
        StringBuffer Keysb = new StringBuffer();
        for (int i = 0; i < KeyLength; i++) // 生成指定位数的随机秘钥字符串
        {
            int number = random.nextInt(base.length());
            Keysb.append(base.charAt(number));
        }
        return Keysb.toString();
    }

    /**
     * AES加密
     * @param data
     * @param key
     * @return
     * @throws Exception
     */
    public static String encrypt(String data, String key) throws Exception {
        byte[] bytes = AES_CBC_Encrypt(data.getBytes("utf-8"), key.getBytes(), key.substring(0, 16).getBytes());
        return encryptBASE64(bytes);
    }

    /**
     * AES解密
     * @param data
     * @param key
     * @return
     * @throws Exception
     */
    public static String decrypt(String data, String key) {
        try {
            byte[] bytes1 = AES_CBC_Decrypt(decryptBASE64(data), key.getBytes("utf-8"), key.substring(0, 16).getBytes());
            return new String(bytes1, "utf-8");
        } catch (Exception e) {
            return null;
        }
    }

    public static void main(String[] args) throws Exception {

        String test = "qyh1122";
        String key = "1qaz3edc5tgb7ujm";
        /*byte[] bytes = AES_CBC_Encrypt(test.getBytes("utf-8"), key.getBytes(), key.substring(0, 16).getBytes());
        String encrypt = encryptBASE64(bytes);
        System.out.println("加密后:" + encrypt);*/

        byte[] bytes1 = AES_CBC_Decrypt(decryptBASE64("13795451560"), key.getBytes("utf-8"), key.substring(0, 16).getBytes());
        String decrypt = new String(bytes1, "utf-8");
        System.out.println("解密后：" + decrypt);

    }

   /* public static void main(String[] args) throws Exception {

        List<String> list = Arrays.asList("xc111111", "xc843109", "xc216843", "xc909346", "xc257798", "xc878769", "xc154688", "xc308221", "xc948989", "xc356134", "xc442794", "xc662655", "xc497579", "xc360570", "xc117131", "xc143149", "xc975749", "xc752449", "xc463643", "xc403920", "xc615600", "xc520323", "xc984116", "xc532502", "xc298053", "xc739680", "xc685591", "xc352686", "xc353027", "xc970474", "xc971828", "xc575493", "xc208183", "xc555170", "xc571637", "xc532432", "xc524118", "xc685202", "xc539546", "xc242674", "xc665720", "xc843404", "xc853864", "xc360927", "xc015678", "xc413973", "xc737906", "xc236780", "xc736777", "xc324423", "xc986399", "xc222575", "xc468149", "xc990264", "xc735303", "xc384207", "xc430154", "xc239386", "xc491816", "xc008854", "xc624460", "xc188246", "xc175271", "xc320957", "xc583175", "xc226025", "xc520438", "xc390752", "xc554956", "xc557992", "xc684223", "xc125847", "xc672246", "xc499003", "xc497517", "xc475954", "xc633413", "xc003072", "xc404610", "xc664890", "xc311970", "xc432415", "xc733310", "xc503590", "xc916927", "xc531132", "xc428446", "xc299596", "xc651204", "xc641611", "xc871055", "xc562628", "xc693531", "xc496860", "xc895132", "xc500868", "xc429907", "xc439392", "xc158932", "xc431142", "xc405920", "xc881111", "xc263009", "xc671418", "xc750130", "xc540518", "xc580914", "xc606100", "xc846256", "xc126687", "xc012444", "xc241638", "xc713088", "xc778653", "xc403194", "xc737394", "xc414197", "xc029746", "xc990470", "xc682499", "xc760721", "xc291697", "xc819572", "xc493340", "xc460128", "xc183658", "xc625252", "xc061689", "xc406345", "xc934317", "xc097520", "xc219339", "xc039067", "xc139932", "xc218331", "xc991370", "xc189680", "xc067461", "xc345241", "xc794142", "xc098594", "xc042574", "xc596627", "xc473813", "xc333906", "xc368644", "xc860412", "xc709508", "xc830891", "xc906804", "xc960004", "xc156076", "xc650336", "xc353413", "xc278627", "xc552006", "xc209903", "xc046444", "xc465991", "xc090994", "xc010153", "xc371836", "xc840962", "xc206382", "xc477501", "xc858273", "xc426726", "xc101672", "xc147077", "xc510601", "xc655688", "xc099935", "xc120308", "xc727282", "xc770874", "xc735612", "xc221551", "xc053495", "xc051364", "xc362915", "xc767765", "xc816674", "xc756608", "xc905691", "xc465861", "xc153021", "xc562927", "xc002162", "xc441950", "xc062083", "xc699593", "xc426313", "xc118544", "xc477079", "xc425839", "xc296308", "xc700869", "xc911679", "xc146471", "xc097528", "xc856402", "xc261227", "xc342143");

        for(String pass : list) {
            String key = "nova4rfv6yhnnova";
            byte[] bytes = AES_CBC_Encrypt(pass.getBytes("utf-8"), key.getBytes(), key.substring(0, 16).getBytes());
            String encrypt = encryptBASE64(bytes);
            System.out.println(encrypt);
        }
    }*/

}
